// BlockOperation.cpp: implementation of the BlockOperation class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "BlockOperation.h"
#include "UEEntityOperation.h"
#include <dbsymtb.h>
#include <geassign.h>
#include <migrtion.h>
#include <math.h>
#include <dbents.h>
#include <aced.h>
#include "WndOperation.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

BlockOperation::BlockOperation()
{

}

BlockOperation::~BlockOperation()
{

}

Acad::ErrorStatus BlockOperation::InsertBlock(const CString& strBlock,
											  const AcGeMatrix3d& matrix,
											  AcDbObjectId& id,
											  const CString& strLayer,
											  AcDbDatabase* pDB)
{
	ASSERT(!strBlock.IsEmpty());
	Acad::ErrorStatus es;
	
	AcDbDatabase* pCurDB = pDB;
	if(pCurDB == NULL)
		pCurDB = acdbCurDwg();
	
	ASSERT(pCurDB);

	es = InsertBlock(strBlock, pCurDB, id);
	if(es != Acad::eOk)
	{
		ASSERT(FALSE);
		return es;
	}

	AcDbBlockReference* pReference = new AcDbBlockReference(AcGePoint3d(), id);

	pReference->transformBy(matrix);

	es = CUEEntityOperation::AddEntityToDwg(pReference, strLayer, FALSE);
	if(es != Acad::eOk)
	{
		ASSERT(FALSE);
		return es;
	}
	id = pReference->objectId();
	pReference->close();

	return Acad::eOk;
}

CString BlockOperation::GetBlockName(const CString& strBlock)
{
	return FileSystemOperation::GetFileName(strBlock);
}

BOOL BlockOperation::FindBlock(AcDbDatabase* pDB, const CString& strBlockName, AcDbObjectId& id)
{
	ASSERT(pDB);
	Acad::ErrorStatus es;
	
	AcDbBlockTable* pBT = NULL;
	es = pDB->getBlockTable(pBT, AcDb::kForRead);
	if(es != Acad::eOk)
	{
		ASSERT(FALSE);
		return FALSE;
	}

	BOOL bResult = pBT->has(strBlockName);
	if(bResult)
		pBT->getAt(strBlockName, id);
	
	pBT->close();

	return bResult;
/*	AcDbBlockTableIterator* pIterator = NULL;
	es = pBT->newIterator(pIterator);
	if(es != Acad::eOk)
	{
		ASSERT(FALSE);
		pBT->close();
		return FALSE;
	}
	pBT->close();

	AcDbBlockTableRecord* pRecord = NULL;
	for(pIterator->start(); !pIterator->done(); pIterator->step())
	{
		es = pIterator->getRecord(pRecord, AcDb::kForRead);
		if(es != Acad::eOk)
		{
			ASSERT(FALSE);
			delete pIterator;
			return FALSE;
		}
		const TCHAR* pName = NULL;
		es = pRecord->getName(pName);
		if(es != Acad::eOk)
		{
			ASSERT(FALSE);
			pRecord->close();
			delete pIterator;
			return FALSE;
		}
		if(strBlockName == CString(pName))
		{
			id = pRecord->objectId();
			pRecord->close();
			delete pIterator;
			return TRUE;
		}
		pRecord->close();
	}
	delete pIterator;
	return FALSE;*/
}

Acad::ErrorStatus BlockOperation::InsertBlock(const CString& strBlock, AcDbDatabase* pDB, AcDbObjectId& id)
{
	ASSERT(!strBlock.IsEmpty());
	ASSERT(pDB);

	CString strBlockName = GetBlockName(strBlock);

	if(FindBlock(pDB, strBlockName, id))
		return Acad::eOk;

	return AddNewBlock(pDB, strBlock, strBlockName, id);	
}

Acad::ErrorStatus BlockOperation::AddNewBlock(AcDbDatabase* pDB, const CString& strBlock,
											  const CString& strBlockName, AcDbObjectId& id)
{
	ASSERT(pDB);
	ASSERT(!strBlock.IsEmpty());
	ASSERT(!strBlockName.IsEmpty());
	
	Acad::ErrorStatus es;
	AcDbDatabase blockDB( Adesk::kFalse);
	es = blockDB.readDwgFile(strBlock);
	if(es != Acad::eOk)
	{
		ASSERT(FALSE);
		return es;
	}

	es = pDB->insert(id, strBlockName, &blockDB);
	if(es != Acad::eOk)
	{
		ASSERT(FALSE);
		return es;
	}

	return es;
}


Acad::ErrorStatus LayerOperation::AddLayer(const CString& strName,
						   AcDbObjectId& id,
						   AcDbDatabase* pDB)
{
	ASSERT(!strName.IsEmpty());

	Acad::ErrorStatus es = Acad::eOk;
	
	AcDbDatabase* pCurDB = pDB;
	if(pCurDB == NULL)
		pCurDB = acdbCurDwg();

	AcDbLayerTable* pTable = NULL;
	es = pCurDB->getLayerTable(pTable, AcDb::kForWrite);
	if(es != Acad::eOk)
	{
		ASSERT(FALSE);
		return es;
	}

	ASSERT(pTable);
	if(pTable->has(strName))
	{
		pTable->close();
		return Acad::eOk;
	}

	AcDbLayerTableRecord* pRecord = new AcDbLayerTableRecord;
	pRecord->setName(strName);
	es = pTable->add(id, pRecord);
	pTable->close();
	pRecord->close();

	return es;
}

AcDbLayerTableRecord* LayerOperation::GetLayer(const CString& strName, AcDbDatabase* pDB)
{
	Acad::ErrorStatus es = Acad::eOk;
	
	AcDbDatabase* pCurDB = pDB;
	if(pCurDB == NULL)
		pCurDB = acdbCurDwg();
	
	AcDbLayerTable* pTable = NULL;
	es = pCurDB->getLayerTable(pTable, AcDb::kForWrite);
	if(es != Acad::eOk)
	{
		ASSERT(FALSE);
		return NULL;
	}

	AcDbLayerTableRecord* pRecord = NULL;
	es = pTable->getAt(strName, pRecord, AcDb::kForWrite);
	if(es != Acad::eOk)
	{
		pTable->close();
		return NULL;
	}

	pTable->close();

	return pRecord;
}

#pragma warning (disable:4800)
void LayerOperation::FrozenLayer(const CString& strName, BOOL IsFrozen, AcDbDatabase* pDB)
{
	AcDbLayerTableRecord* pRecord = GetLayer(strName, pDB);
	if(pRecord == NULL)
		return;

	pRecord->setIsFrozen((bool)IsFrozen);
	pRecord->close();
}